package com.owc.common.context;

import com.owc.common.enums.ExceptionEnum;
import com.owc.common.exception.BadRequestException;
import com.owc.common.Const.Const;
import com.owc.domain.UserExample;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

/**
 * Global session manage
 * @author Xiaoming
 */
@Slf4j
public class SessionHelper {

    public static final ThreadLocal<UserExample> THREAD_LOCAL = new ThreadLocal<>();

    /**
     *
     * Get current thread httpServletRequest
     */
    @NonNull
    public static HttpServletRequest getContextRequest(){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        Assert.notNull(requestAttributes,"Get current thread requestAttributes example fail");

        return ((ServletRequestAttributes)requestAttributes).getRequest();
    }

    /**
     *
     * Get current thread httpServletRequest
     */
    @NonNull
    public static HttpServletResponse getContextResponse(){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        Assert.notNull(requestAttributes,"Get current thread requestAttributes example fail");

        return ((ServletRequestAttributes)requestAttributes).getResponse();
    }

    /**
     * Get current thread request session id
     */
    @NonNull
    public static String getContextRequestId(){
        HttpServletRequest request = getContextRequest();
        return request.getSession().getId();
    }

    /**
     * Get current thread request header value by headerKey.
     */
    public static Optional<String> getRequestHeader(@NonNull String headerKey){
        HttpServletRequest request = getContextRequest();
        return Optional.ofNullable(request.getHeader(headerKey));
    }

    /**
     * Get request client type.
     */
    @NonNull
    public static Integer getRequestClient(){
        return getRequestHeader(Const.CLIENT)
                .map(Integer::new)
                .orElseThrow(() -> new BadRequestException(ExceptionEnum.REQUEST_PARAMS_ERR));
    }

    @Nullable
    public static String getRequestVersion(){
        return getRequestHeader(Const.API_VERSION)
                .orElse(null);
    }

    /**
     * Get request client type.
     */
    @Nullable
    public static String getRequestToken(){
        return getRequestHeader(Const.TOKEN)
                .orElseThrow(() -> new BadRequestException(ExceptionEnum.REQUEST_PARAMS_ERR));
    }

    public static void buildTestUser(){
        UserExample example = new UserExample();
        example.setId(3L);
        THREAD_LOCAL.set(example);
    }
}
